class Socket {
  connect = null

  events = {}
  
  config = {
    isExit: false,
    heartbeat: {
      setInterval: null,
      pingInterval: 20000,
    },
    reconnect: {
      lockReconnect: 0,
      setTimeout: null, // 计时器对象
      time: 3000, // 重连间隔时间
      number: 10000000, // 重连次数
    },
  }

  constructor(bindEvent) {
    this.config.isExit = false
    this.onEvent(bindEvent)
    this.loadSocket()
  }

  loadSocket() {
    const websocketUrl = process.env.VUE_APP_WS + sessionStorage.getItem('token')
    this.connect = new WebSocket(websocketUrl)
    this.connect.onopen = this.onOpen.bind(this)
    this.connect.onmessage = this.onMessage.bind(this)
    this.connect.onerror = this.onError.bind(this)
    this.connect.onclose = this.onClose.bind(this)
  }

  onOpen(e) {
    this.heartbeat() 
  }

  onMessage(e) {
    try {
      const data = JSON.parse(e.data)
      const type = data.type

      // switch (type) {
      //   case 'pong':
      //     break;
      //   default:
          
      //     break;
      // }
      this.emit(type,data.data)
    } catch (error) {
      console.log(new Date().toTimeString()+"：",error)
    }
  }

  onError(e) {
    console.log("onError",e)
    this.clear(true,{
      title: "连接出错",
      message: "正在重新连接中！"
    })
  }

  onClose() {
    this.clear(!this.config.isExit,{
      title: "连接中断",
      message: "正在重新连接中！"
    })
  }

  exit() {
    this.config.isExit = true
    this.clear()
  }

  /**
   * 
   * @param {*Boolean} falg - 是否重连
   * @param {*{title:"",message:""}} connectError - 报错提示
   */
  clear(falg,connectError={}) {
    clearInterval(this.config.heartbeat.setInterval)
    
    this.connect && this.connect.close()
    this.connect = null

    if(falg) {
      // this.emit("connectError",connectError)
      this.reconnect()
    }
  }


  reconnect() {
    clearTimeout(this.config.reconnect.setTimeout)

    this.config.reconnect.setTimeout = setTimeout(() => {
      if(!(this.connect && this.connect.readyState === 1)){
        this.loadSocket()
      }

    }, this.config.reconnect.time)

  }

  heartbeat() {
    this.config.heartbeat.setInterval = setInterval(() => {
      this.ping()
    }, this.config.heartbeat.pingInterval)
  }

  ping() {
    this.send({
      action: "ping"
    })
  }

  send(ops,cb) {
    if(this.connect && this.connect.readyState === 1 ){

      if(ops){
        this.connect.send(JSON.stringify(ops))
      }
      
      if(typeof cb === 'function') cb(ops)

    }else{
      this.clear(true,{
        title: "消息发送失败！",
        message: "连接中断，正在重新连接中！"
      })
    }

  }


  onEvent(bindEvent) {
    this.events = bindEvent
  }

  on(eventName, callBack) {
    this.events[eventName] = callBack
    return this
  }

  emit(eventName,ops={}) {
    if(typeof this.events[eventName] == 'function'){
      return this.events[eventName](ops)
    }else {
      throw new Error(eventName + "-该事件未注册！")
    }
  }
}


export default Socket